package com.yincb.controller;

import com.yincb.service.DynamicBeanRegistrationService;
import com.yincb.service.DynamicBeanRegistrationService.BeanRegistrationResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/dynamic-beans")
public class DynamicBeanController {
    
    private static final Logger logger = LoggerFactory.getLogger(DynamicBeanController.class);
    
    @Autowired
    private DynamicBeanRegistrationService beanRegistrationService;
    
    /**
     * 注册动态Bean
     * @param request 注册请求
     * @return 注册结果
     */
    @PostMapping("/register")
    public ResponseEntity<Map<String, Object>> registerBean(@RequestBody RegisterBeanRequest request) {
        logger.info("收到注册动态Bean请求: {}", request.getBeanName());
        
        try {
            // 验证请求参数
            if (request.getSourceCode() == null || request.getSourceCode().trim().isEmpty()) {
                return createErrorResponse("源代码不能为空", HttpStatus.BAD_REQUEST);
            }
            
            if (request.getClassName() == null || request.getClassName().trim().isEmpty()) {
                return createErrorResponse("类名不能为空", HttpStatus.BAD_REQUEST);
            }
            
            // 注册Bean
            BeanRegistrationResult result;
            if (request.getBeanName() != null && !request.getBeanName().trim().isEmpty()) {
                result = beanRegistrationService.registerBean(
                    request.getBeanName().trim(), 
                    request.getClassName().trim(), 
                    request.getSourceCode()
                );
            } else {
                result = beanRegistrationService.registerBean(
                    request.getClassName().trim(), 
                    request.getSourceCode()
                );
            }
            
            // 构建响应
            Map<String, Object> response = new HashMap<>();
            response.put("success", result.isSuccess());
            response.put("beanName", result.getBeanName());
            response.put("className", result.getClassName());
            
            if (result.isSuccess()) {
                response.put("message", "Bean注册成功");
                response.put("beanInstance", result.getBeanInstance().toString());
                return ResponseEntity.ok(response);
            } else {
                response.put("message", "Bean注册失败");
                response.put("error", result.getErrorMessage());
                return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
            }
            
        } catch (Exception e) {
            logger.error("注册动态Bean时发生异常", e);
            return createErrorResponse("注册失败: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
    
    /**
     * 获取Bean信息
     * @param beanName Bean名称
     * @return Bean信息
     */
    @GetMapping("/{beanName}")
    public ResponseEntity<Map<String, Object>> getBeanInfo(@PathVariable String beanName) {
        logger.info("查询Bean信息: {}", beanName);
        
        try {
            if (!beanRegistrationService.isBeanExists(beanName)) {
                return createErrorResponse("Bean不存在: " + beanName, HttpStatus.NOT_FOUND);
            }
            
            Object beanInstance = beanRegistrationService.getBean(beanName);
            Class<?> beanType = beanRegistrationService.getBeanType(beanName);
            
            Map<String, Object> response = new HashMap<>();
            response.put("beanName", beanName);
            response.put("className", beanType.getName());
            response.put("simpleClassName", beanType.getSimpleName());
            
            // 安全地获取包名，避免NullPointerException
            Package pkg = beanType.getPackage();
            String packageName;
            if (pkg != null) {
                packageName = pkg.getName();
            } else {
                // 从类名中提取包名
                String className = beanType.getName();
                int lastDotIndex = className.lastIndexOf('.');
                packageName = lastDotIndex != -1 ? className.substring(0, lastDotIndex) : "default";
            }
            response.put("packageName", packageName);
            
            response.put("beanInstance", beanInstance.toString());
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            logger.error("查询Bean信息时发生异常", e);
            return createErrorResponse("查询失败: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
    
    /**
     * 移除Bean
     * @param beanName Bean名称
     * @return 移除结果
     */
    @DeleteMapping("/{beanName}")
    public ResponseEntity<Map<String, Object>> removeBean(@PathVariable String beanName) {
        logger.info("移除Bean: {}", beanName);
        
        try {
            boolean removed = beanRegistrationService.removeBean(beanName);
            
            Map<String, Object> response = new HashMap<>();
            response.put("success", removed);
            response.put("beanName", beanName);
            
            if (removed) {
                response.put("message", "Bean移除成功");
                return ResponseEntity.ok(response);
            } else {
                response.put("message", "Bean不存在");
                return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response);
            }
            
        } catch (Exception e) {
            logger.error("移除Bean时发生异常", e);
            return createErrorResponse("移除失败: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
    
    /**
     * 获取所有动态Bean名称
     * @return 所有Bean名称列表
     */
    @GetMapping("/list")
    public ResponseEntity<Map<String, Object>> listAllBeans() {
        logger.info("查询所有动态Bean");
        
        try {
            String[] beanNames = beanRegistrationService.getAllDynamicBeanNames();
            
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("beanCount", beanNames.length);
            response.put("beanNames", beanNames);
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            logger.error("查询所有Bean时发生异常", e);
            return createErrorResponse("查询失败: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
    
    /**
     * 测试动态Bean方法调用
     * @param beanName Bean名称
     * @param methodName 方法名
     * @param request 请求参数
     * @return 方法调用结果
     */
    @PostMapping("/{beanName}/invoke/{methodName}")
    public ResponseEntity<Map<String, Object>> invokeBeanMethod(
            @PathVariable String beanName,
            @PathVariable String methodName,
            @RequestBody Map<String, Object> request) {
        
        logger.info("调用Bean方法: {}.{}", beanName, methodName);
        
        try {
            if (!beanRegistrationService.isBeanExists(beanName)) {
                return createErrorResponse("Bean不存在: " + beanName, HttpStatus.NOT_FOUND);
            }
            
            Object beanInstance = beanRegistrationService.getBean(beanName);
            
            // 获取方法参数
            Object[] args = request.containsKey("args") ? 
                ((List<?>) request.get("args")).toArray() : new Object[0];
            
            // 使用方法名和参数类型查找方法
            Method method = findMethod(beanInstance.getClass(), methodName, args);
            if (method == null) {
                return createErrorResponse("方法不存在: " + methodName, HttpStatus.BAD_REQUEST);
            }
            
            // 调用方法
            Object result = method.invoke(beanInstance, args);
            
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("beanName", beanName);
            response.put("methodName", methodName);
            response.put("result", result);
            response.put("resultType", result != null ? result.getClass().getSimpleName() : "null");
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            logger.error("调用Bean方法时发生异常", e);
            return createErrorResponse("调用失败: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
    
    /**
     * 查找方法（支持重载）
     */
    private Method findMethod(Class<?> clazz, String methodName, Object[] args) {
        Method[] methods = clazz.getMethods();
        
        for (Method method : methods) {
            if (!method.getName().equals(methodName)) {
                continue;
            }
            
            Class<?>[] paramTypes = method.getParameterTypes();
            if (paramTypes.length != args.length) {
                continue;
            }
            
            // 检查参数类型是否匹配
            boolean matches = true;
            for (int i = 0; i < paramTypes.length; i++) {
                if (args[i] != null && !isCompatibleType(args[i].getClass(), paramTypes[i])) {
                    matches = false;
                    break;
                }
            }
            
            if (matches) {
                return method;
            }
        }
        
        return null;
    }
    
    /**
     * 检查类型兼容性
     */
    private boolean isCompatibleType(Class<?> actualType, Class<?> expectedType) {
        if (expectedType.isAssignableFrom(actualType)) {
            return true;
        }
        
        // 处理基本类型和包装类型的转换
        if (expectedType.isPrimitive()) {
            return isWrapperType(actualType, expectedType);
        }
        
        return false;
    }
    
    /**
     * 检查是否为包装类型
     */
    private boolean isWrapperType(Class<?> wrapperType, Class<?> primitiveType) {
        return (primitiveType == int.class && wrapperType == Integer.class) ||
               (primitiveType == long.class && wrapperType == Long.class) ||
               (primitiveType == double.class && wrapperType == Double.class) ||
               (primitiveType == float.class && wrapperType == Float.class) ||
               (primitiveType == boolean.class && wrapperType == Boolean.class) ||
               (primitiveType == char.class && wrapperType == Character.class) ||
               (primitiveType == byte.class && wrapperType == Byte.class) ||
               (primitiveType == short.class && wrapperType == Short.class);
    }
    
    /**
     * 创建错误响应
     */
    private ResponseEntity<Map<String, Object>> createErrorResponse(String message, HttpStatus status) {
        Map<String, Object> response = new HashMap<>();
        response.put("success", false);
        response.put("message", message);
        return ResponseEntity.status(status).body(response);
    }
    
    /**
     * 注册Bean请求DTO
     */
    public static class RegisterBeanRequest {
        private String beanName;
        private String className;
        private String sourceCode;
        
        // Getters and Setters
        public String getBeanName() {
            return beanName;
        }
        
        public void setBeanName(String beanName) {
            this.beanName = beanName;
        }
        
        public String getClassName() {
            return className;
        }
        
        public void setClassName(String className) {
            this.className = className;
        }
        
        public String getSourceCode() {
            return sourceCode;
        }
        
        public void setSourceCode(String sourceCode) {
            this.sourceCode = sourceCode;
        }
    }
}